package panels;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

import logger.Logger;
import sprites.CircleSprite;
import sprites.ImageSprite;
import sprites.LineSprite;
import sprites.PointSetSprite;
import sprites.RectangleSprite;
import sprites.RoundedCornersSprite;
import sprites.Sprite;
import util.DrawSet;
import xml.Xml;
import classes.Func;
import classes.SelectionMode;

public class PaintPanel extends MapPanel implements PopupMenuListener {
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	//
	// Map interface methods
	//
	public static final int	SELECT_TILES_BUTTON				= LEFT_BUTTON;
	public static final int MOVE_ACTORS_AND_CANVAS_BUTTON	= RIGHT_BUTTON;
	public static final int POP_UP_MENU_BUTTON				= CENTER_BUTTON;

	public static final String	SELECTION_MODE_PROPERTY		= "SELECTION_MODE_PROPERTY";
	public static final String	SELECTED_SPRITE_PROPERTY	= "SELECTED_SPRITE_PROPERTY";

	public static final SelectionMode	defaultSelectionMode = SelectionMode.brush;

	private 		SelectionModeMenu 			spriteTypeMenu;
	private 		SelectionMode				selectionMode = defaultSelectionMode;
	JColorChooser	colorChooser = new JColorChooser();
	JFileChooser	imageChooser = new JFileChooser();

	private Color	spriteColor = Sprite.defaultColor;
	private Color	textColor	= Color.black;
	private Sprite	selectedSprite = null;
	private boolean	roundCorners = false;
	private Image	spriteImage = null;



	public Color getTextColor() {
		return textColor;
	}

	public void setTextColor(Color textColor) {
		this.textColor = textColor;
	}

	public Sprite getSelectedSprite() {
		return selectedSprite;
	}

	public void setSelectedSprite(Sprite newSprite) {
		Sprite oldSprite = this.getSelectedSprite();

		if (oldSprite != null) {
			oldSprite.setSelected(false);
		}
		this.selectedSprite = newSprite;

		if (this.selectedSprite != null) {
			this.getSprites().remove(this.selectedSprite);
			this.getSprites().add(this.getSprites().size(),this.selectedSprite);
			this.selectedSprite.setSelected(true);
			this.selectedSprite.setOldPos(this.selectedSprite.getPos());
		}

		if (!Func.equals(oldSprite, newSprite)) {
			this.firePropertyChange(SELECTED_SPRITE_PROPERTY, oldSprite, newSprite);
		}

		refresh();
	}

	public SelectionMode	getSelectionMode() {
		return this.selectionMode;
	}

	public void setSelectionMode(SelectionMode newMode) {
		SelectionMode	oldMode = this.getSelectionMode();
		if (newMode!= oldMode) {
			selectionMode = newMode;

			spriteTypeMenu.setSelected(newMode);
			this.firePropertyChange(SELECTION_MODE_PROPERTY, oldMode, newMode);
			this.refresh();
		}
	}

	public Color getSpriteColor() {
		return spriteColor;
	}

	public void setSpriteColor(Color spriteColor) {
		this.spriteColor = spriteColor;
		if (getSelectedSprite()!=null) {
			setSelectedColor(spriteColor);
			getSelectedSprite().setColor(spriteColor);
			refresh();
		}
	}


	public boolean isRoundCorners() {
		return roundCorners;
	}

	public void setRoundCorners(boolean roundCorners) {
		this.roundCorners = roundCorners;
	}
	/**
	 * Create the panel.
	 */
	public PaintPanel() {
		super();

		setLayout(new BorderLayout(0, 0));

		JMenuBar menuBar = new JMenuBar();
		add(menuBar, BorderLayout.NORTH);

		JMenu fileMenu = new JMenu("File");
		menuBar.add(fileMenu);

		JMenuItem loadMenuItem = new JMenuItem("Load");
		loadMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				loadMap("***** INSERT FILENAME HERE *****");
			}
		});
		fileMenu.add(loadMenuItem);

		JMenuItem saveMenuItem = new JMenuItem("Save");
		saveMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				saveMap("**** INSERT FILENAME HERE *****");
			}
		});
		fileMenu.add(saveMenuItem);

		JMenu allSpritesMenu = new JMenu("All");
		menuBar.add(allSpritesMenu);

		JMenuItem deleteAllSpritesMenuItem = new JMenuItem("Delete");
		deleteAllSpritesMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				DeleteAllSprites();
			}
		});
		allSpritesMenu.add(deleteAllSpritesMenuItem);

		JMenuItem changeAllColorsMenuItem = new JMenuItem("Change Color");
		changeAllColorsMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				ChangeSpritesColor(getAllSprites(), getSpriteColor());
				refresh();
			}
		});
		allSpritesMenu.add(changeAllColorsMenuItem);

		JMenu selectedMenu = new JMenu("Selected");
		menuBar.add(selectedMenu);

		JMenuItem deleteSelectedMenuItem = new JMenuItem("Delete");
		selectedMenu.add(deleteSelectedMenuItem);

		JMenuItem changeSelectedColorMenuItem = new JMenuItem("Change Color");
		changeSelectedColorMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				ChangeSpritesColor(getSelectedSprites(), getSpriteColor());
				refresh();
			}
		});
		selectedMenu.add(changeSelectedColorMenuItem);

		spriteTypeMenu = new SelectionModeMenu();
		menuBar.add(spriteTypeMenu);
		spriteTypeMenu.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				setSelectionMode(spriteTypeMenu.getSelection());
				refresh();
			}
		});
		spriteTypeMenu.setText("Sprite");

		final JCheckBox roundCornersCheckBox = new JCheckBox("Round Corners");
		spriteTypeMenu.add(roundCornersCheckBox);
		roundCornersCheckBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setRoundCorners(roundCornersCheckBox.isSelected());
			}
		});
		setRoundCorners(roundCornersCheckBox.isSelected());

		JMenu colorMenu = new JMenu("Color");
		menuBar.add(colorMenu);

		JMenuItem spriteColorMenuItem = new JMenuItem("Sprite");
		colorMenu.add(spriteColorMenuItem);

		JMenuItem backgroundColorMenuItem = new JMenuItem("Background");
		backgroundColorMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseBackgroundColor();
			}
		});
		colorMenu.add(backgroundColorMenuItem);

		JMenuItem foregroundColorMenuItem = new JMenuItem("Foreground");
		foregroundColorMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseForegroundColor();
			}
		});
		colorMenu.add(foregroundColorMenuItem);

		JMenuItem gridColorMenuItem = new JMenuItem("Grid");
		gridColorMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseGridColor();
			}
		});
		colorMenu.add(gridColorMenuItem);

		JMenuItem textColorMenuItem = new JMenuItem("Text");
		textColorMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseTextColor();
			}
		});
		colorMenu.add(textColorMenuItem);

		JMenuItem selectedImageMenuItem = new JMenuItem("Image");
		selectedImageMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseSpriteImage();
			}
		});
		colorMenu.add(selectedImageMenuItem);
		spriteColorMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				chooseSpriteColor();
			}
		});
		deleteSelectedMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				DeleteSelectedSprites();
				refresh();
			}
		});

		setSelectionMode(defaultSelectionMode);

		menuBar.setVisible(true);

		colorChooser = new JColorChooser();
		colorChooser.setColor(Sprite.defaultColor);

		this.setDrawMouse(true);

		this.setGridColor(new Color(192, 192, 192));
		this.setBackground(new Color(128, 128, 128));
		this.setForeground(new Color(0, 0, 0));
		this.setSelectedColor(Color.CYAN);
		this.setTextColor(Color.darkGray);
		this.setSpriteColor(Color.blue);

		setDebug(false);
	}


	public Image getSpriteImage() {
		return spriteImage;
	}

	public void setSpriteImage(Image spriteImage) {
		this.spriteImage = spriteImage;
	}

	//
	// INTERNAL METHODS
	//

	public void ChangeSpritesColor(Collection<Sprite> collection, Color C) {
		Iterator<Sprite>	itr = collection.iterator();
		Sprite				S;

		while(itr.hasNext()) {
			S = itr.next();
			S.setColor(C);
		}
	}

	//
	// INPUT METHODS
	//

	@Override
	public void mousePressed(MouseEvent e) {
		//
		// Desired Controls
		//	LEFT BUTTON
		//		on canvas	=> selects tiles resulting on selected actors
		//		on actor	=> toggles selection of an actor and allows movement of all selected actors
		//
		//	MIDDLE BUTTON
		//		on canvas brings up the area selection menu
		//		on actor brings up the properties of that actor
		//
		//	RIGHT BUTTON
		//		on press	=> allows the movement of the origon
		//		on wheel	=> alters the zoom state
		//

		super.mousePressed(e);

		Sprite	toBeSelected = null;

		if (e.getButton() == SELECT_TILES_BUTTON) {
			this.selectTiles = true;
		}

		if (e.getButton() == MOVE_ACTORS_AND_CANVAS_BUTTON) {
			Iterator<Sprite>	itr = getAllSprites().iterator();
			toBeSelected = null;

			while(itr.hasNext()) {
				Sprite A = itr.next();
				if (A.containsPoint((Point) mCanvasPos)) {

					toBeSelected = A;
				}
			}
			this.moveCanvas = (toBeSelected == null);
			this.moveActors = !this.moveCanvas;

			this.setSelectedSprite(toBeSelected);
			refresh();
		}

		if (e.getButton() == POP_UP_MENU_BUTTON) {
		}

	}
	@Override
	public void mouseReleased(MouseEvent e) {
		super.mouseReleased(e);
		//
		// Desired Controls
		//	LEFT BUTTON
		//		on canvas	=> selects tiles resulting on selected actors
		//		on actor	=> toggles selection of an actor and allows movement of all selected actors
		//
		//	MIDDLE BUTTON
		//		on canvas brings up the area selection menu
		//		on actor brings up the properties of that actor
		//
		//	RIGHT BUTTON
		//		on press	=> allows the movement of the origon
		//		on wheel	=> alters the zoom state
		//
		if (e.getButton() == PaintPanel.SELECT_TILES_BUTTON) {
			this.selectTiles = false;
			Sprite S = null;
			Point	Pstart	= (Point) this.mCanvasDown.get(PaintPanel.SELECT_TILES_BUTTON);
			Point	Pend	= (Point) this.mCanvasPos;

			if (this.getSelectionMode() == SelectionMode.line) {

				if (!isRoundCorners()) {
					S = new LineSprite(Pstart,Pend);
				} else {
					S = new RoundedCornersSprite(Pend, this.selected);
				}

			} else if (this.getSelectionMode() == SelectionMode.circle) {

				if (!isRoundCorners()) {
					S = new CircleSprite(Pstart, (int) Pstart.distance(Pend));
				} else {
					S = new RoundedCornersSprite(Pend, this.selected);
				}

			} else if (this.getSelectionMode() == SelectionMode.rectangle) {

				int	minX = Math.min(Pstart.x, Pend.x);
				int minY = Math.min(Pstart.y, Pend.y);
				int maxX = Math.max(Pstart.x,  Pend.x);
				int maxY = Math.max(Pstart.y,  Pend.y);

				if (!isRoundCorners()) {
					if (this.getSpriteImage()==null) {
						S = new RectangleSprite(
							new Point(minX, minY),
							new Dimension(maxX-minX+1, maxY-minY+1)
						);
					} else {
						S = new ImageSprite(
								new Point(minX, minY),
								new Dimension(maxX-minX+1, maxY-minY+1),
								this.getSpriteImage()
							);
					}
				} else {
					S = new RoundedCornersSprite(Pend, this.selected);
				}

			} else {
				if (!isRoundCorners()) {
					S = new PointSetSprite(Pend, this.selected);
				} else {
					S = new RoundedCornersSprite(Pend, this.selected);
				}

			}

			if (S!=null) {
				S.setColor(this.getSpriteColor());
				getSprites().add(S);
			}
			this.selected = new HashSet<Point>();
			refresh();

		} else if (e.getButton() == PaintPanel.MOVE_ACTORS_AND_CANVAS_BUTTON) {
			this.moveActors = false;
			this.moveCanvas = false;
		} else if (e.getButton() == PaintPanel.POP_UP_MENU_BUTTON) {

		}


	}
	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {
		super.mouseWheelMoved(e);

		if (e.getWheelRotation() < 0d) {
			this.setZoom(getZoom() * 1.1);
		} else {
			this.setZoom(getZoom() / 1.1);
		}
		refresh();
	}
	@Override
	public void mouseMoved(MouseEvent e) {
		super.mouseMoved(e);
	}
	@Override
	public void mouseDragged(MouseEvent e) {
		super.mouseDragged(e);

		Point2D	sDown	= (Point2D) mScreenDown.get(SELECT_TILES_BUTTON);
		Point2D sPos	= mScreenPos;

		int	cxDown		= toTileX((int) sDown.getX());
		int	cyDown		= toTileY((int) sDown.getY());
		int cxPos		= toTileX((int) sPos.getX());
		int	cyPos		= toTileY((int) sPos.getY());

		if (this.selectTiles) {
			if (this.getSelectionMode() == SelectionMode.tile) {
				selected		= DrawSet.getPoint(cxPos, cyPos);
				refresh();
			} else if (this.getSelectionMode() == SelectionMode.brush) {
				selected.add(new Point(cxPos, cyPos));
				refresh();
			} else if (this.getSelectionMode() == SelectionMode.line) {
				selected		= DrawSet.getLine(cxDown, cyDown, cxPos, cyPos);
				refresh();
			} else if (this.getSelectionMode() == SelectionMode.circle) {
				selected		= DrawSet.getCircle(cxDown, cyDown, (int) Point2D.distance(cxDown, cyDown, cxPos, cyPos));
				refresh();
			} else if (this.getSelectionMode() == SelectionMode.rectangle) {
				selected		= DrawSet.getPointRect(cxDown, cyDown, cxPos, cyPos);
				refresh();
			}
		}

		if (this.moveCanvas) {
			Point2D oStart		= mOrigonDown.get(MOVE_ACTORS_AND_CANVAS_BUTTON);

			double	dx = (mScreenPos.getX() - ((Point) mScreenDown.get(MOVE_ACTORS_AND_CANVAS_BUTTON)).getX()) / zoom;
			double	dy = (mScreenPos.getY() - ((Point) mScreenDown.get(MOVE_ACTORS_AND_CANVAS_BUTTON)).getY()) / zoom;

			setOrigon(
				(oStart.getX() + dx),
				(oStart.getY() + dy)
			);
			refresh();
		}

		if (this.moveActors) {
			double	dx = (mScreenPos.getX() - ((Point) mScreenDown.get(MOVE_ACTORS_AND_CANVAS_BUTTON)).getX()) / zoom;
			double	dy = (mScreenPos.getY() - ((Point) mScreenDown.get(MOVE_ACTORS_AND_CANVAS_BUTTON)).getY()) / zoom;

			Iterator<Sprite>	itr = getAllSprites().iterator();
			while(itr.hasNext()) {
				Sprite A = itr.next();
				if (A.isSelected()) {
					A.setPos(
						new Point(
							(int) (A.getOldPos().x + dx),
							(int) (A.getOldPos().y + dy)
						)
					);
				}
			}
			refresh();
		}

	}

	@Override
	public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
		refresh();
	}
	@Override
	public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
		refresh();
	}
	@Override
	public void popupMenuCanceled(PopupMenuEvent e) {
		refresh();
	}

	protected static final int	KEY_DELETE = 127;

	@Override
	public void keyPressed(KeyEvent e) {
		super.keyPressed(e);
		if (e.getKeyCode() == KEY_DELETE) {
			DeleteSelectedSprites();
		}
	}

	//
	// Saving and loading
	//



	public String toXml() {
		/*
		 * <PaintMap>
		 *   <GeneralColors>
		 *     <SpriteColor>
		 *     </SpriteColor>
		 *     <ForegroundColor>
		 *     </ForegroundColor>
		 *     <BackgroundColor>
		 *     </BackgroundColor>
		 *     <GridColor>
		 *     </GridColor>
		 *     <TextColor>
		 *     </TextColor>
		 *   </GeneralColors>
		 *   <Sprites>
		 *     <NumSprites>
		 *     </NumSprites>
		 *     <Sprite_1>
		 *       <SpriteKey>
		 *       </SpriteKey>
		 *       <Sprite>
		 *       </Sprite>
		 *     </Sprite_1>
		 *     .
		 *     .
		 *     <Sprite_N>
		 *     <SpriteKey>
		 *       </SpriteKey>
		 *       <Sprite>
		 *       </Sprite>
		 *     </Sprite_N>
		 *   </Sprites>
		 */
		String spritesStr			= "";
		String generalColorsStr		= "";
		String paintMapStr 			= "";
		String zoomStr				= "";
		String origonLocationStr	= "";

		generalColorsStr = Xml.write("GeneralColors",
				Xml.write("SpriteColor", this.getSpriteColor())
			+	Xml.write("ForegroundColor", this.getForeground())
			+	Xml.write("BackgroundColor", this.getBackground())
			+	Xml.write("GridColor", this.getGridColor())
			+	Xml.write("TextColor", this.getTextColor())
			+	Xml.write("SelectedColor", this.getSelectedColor())
		);

		zoomStr				= Xml.write("Zoom", Double.toString(this.getZoom()));
		origonLocationStr	= Xml.write("Origon", (Point) this.getOrigon());

		Sprite				sprite;
		Iterator<Sprite>	Vitr = this.getAllSprites().iterator();
		int					i=0;
		String				spriteTag;
		String				numSpritesStr = "";
		String				S = "";

		numSpritesStr = Xml.write("NumSprites", Integer.toString(getAllSprites().size()) );

		while(Vitr.hasNext()) {
			sprite = Vitr.next();
			spriteTag = "Sprite_" + Integer.toString(i);

			S += Xml.write(spriteTag,
				Xml.write("Sprite",
					sprite.toXml()
				)
			);
			i++;
		}

		spritesStr = Xml.write("Sprites",
			numSpritesStr +
			S
		);

		paintMapStr = Xml.write("PaintMap",
				generalColorsStr +
				origonLocationStr +
				zoomStr +
				spritesStr
			);

		return paintMapStr;
	}

	public void fromXml(String xml) {
		String paintMapStr			= Xml.getTag(xml, 				"PaintMap");
		String generalColorsStr		= Xml.getTag(paintMapStr,		"GeneralColors");
		String origonLocationStr	= Xml.getTag(paintMapStr,		"Origon");
		String zoomStr				= Xml.getTag(paintMapStr,		"Zoom");
		String spriteColorStr		= Xml.getTag(generalColorsStr,	"SpriteColor");
		String foregroundColorStr	= Xml.getTag(generalColorsStr,	"ForegroundColor");
		String backgroundColorStr	= Xml.getTag(generalColorsStr,	"BackgroundColor");
		String gridColorStr			= Xml.getTag(generalColorsStr,	"GridColor");
		String textColorStr			= Xml.getTag(generalColorsStr,	"TextColor");
		String selectedColorStr		= Xml.getTag(generalColorsStr,	"SelectedColor");
		String spritesStr			= Xml.getTag(paintMapStr,		"Sprites");
		String numSpritesStr		= Xml.getTag(spritesStr,		"NumSprites");


		this.setForeground(		new Color( Integer.parseInt( textColorStr	)));
		this.setForeground(		new Color( Integer.parseInt( foregroundColorStr	)));
		this.setBackground(		new Color( Integer.parseInt( backgroundColorStr	)));
		this.setGridColor(		new Color( Integer.parseInt( gridColorStr		)));
		this.setSpriteColor(	new Color( Integer.parseInt( spriteColorStr		)));
		this.setSelectedColor(	new Color( Integer.parseInt( selectedColorStr	)));


		Point	P = new Point();

		try {
			P = (Point) Xml.readObj(Point.class, origonLocationStr);
		} catch (InstantiationException e) {
			Logger.println("Could not instantiate the sprite location");
			return;
		} catch (IllegalAccessException e) {
			Logger.println("Could not access the sprite location");
			return;
		}

		this.setOrigon(P.getX(), P.getY());

		this.setZoom(Double.parseDouble(zoomStr));

		RoundedCornersSprite		sprite;

		String				spriteInfoStr;
		String				spriteStr;

		int					i, numSprites;
		String				spriteTag;

		numSprites = Integer.parseInt(numSpritesStr);

		for(i=0; i<numSprites; i++) {
			spriteTag		= "Sprite_" + Integer.toString(i);
			spriteInfoStr	= Xml.getTag(spriteTag,spritesStr);
			spriteStr		= Xml.getTag(spriteTag,spriteInfoStr);

			sprite = new RoundedCornersSprite(new Point(0,0), new HashSet<Point>());
			sprite.fromXml(spriteStr);

			//
			// Now that we FINALLY have read in our sprite. Add it to the list of sprites
			//
			if (sprite != null) {
				getSprites().add(sprite);
			}
		}

	}


	public String testString = "";

	public void saveMap(String filename) {
		testString = toXml();
		System.out.println("*********************************");
		System.out.println(testString);
		System.out.println("*********************************");
	}

	public void loadMap(String filename) {
		fromXml(testString);
	}

	public void chooseGridColor() {
		Color	choice = JColorChooser.showDialog(colorChooser, "Grid Color", getGridColor());
		setGridColor(choice);
		refresh();
	}
	public void chooseBackgroundColor() {
		Color	choice = JColorChooser.showDialog(colorChooser, "Background Color", getBackground());
		setBackground(choice);
		refresh();
	}
	public void chooseForegroundColor() {
		Color	choice = JColorChooser.showDialog(colorChooser, "Foreground Color", getForeground());
		setForeground(choice);
		refresh();
	}
	public void chooseSpriteColor() {
		Color	choice = JColorChooser.showDialog(colorChooser, "Sprite Color", getSpriteColor());
		setSpriteColor(choice);
		refresh();
	}
	public void chooseTextColor() {
		Color	choice = JColorChooser.showDialog(colorChooser, "Text Color", getTextColor());
		setTextColor(choice);
		refresh();
	}

	private void chooseSpriteImage() {
		File			choiceFile = null;
		Image			choiceImage = null;

		if (imageChooser!=null) {
			imageChooser.showDialog(imageChooser, "Sprite Image");
			choiceFile = imageChooser.getSelectedFile();
			choiceImage = null;

			if (choiceFile!=null) {
				try {
					choiceImage = ImageIO.read(choiceFile);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			setSpriteImage(choiceImage);
			refresh();
		}
	}

}
